<?php

/**
 * Created by PhpStorm.
 * User: GZJ
 * Date: 2017/5/17
 * Time: 16:32
 */


namespace Admin\Model;
use Think\Model;

class GoodsModel extends Model{

    protected $insertFields = 'goods_name,market_price,shop_price,is_on_sale,goods_desc,brand_id,cat_id,type_id,promote_price,promote_start_date,
   promote_end_date,is_new,is_best,is_hot,sort_num,is_floor';  //添加时允许接收的字段
    protected $updateFields = 'id,goods_name,market_price,shop_price,is_on_sale,goods_desc,brand_id,cat_id,type_id,promote_price,promote_start_date,
   promote_end_date,is_new,is_best,is_hot,sort_num,is_floor'; //修改时允许接收的字段
    //模型负责的是  定义表单验证规则
    protected $_validate = array(
        array('cat_id','require','请选择主分类',1), //第一个是数据库字段 第二个是tp的验证规则  第三个1代表必须验证
        array('goods_name','require','商品名称不能为空',1), //第一个是数据库字段 第二个是tp的验证规则  第三个1代表必须验证
        array('market_price','currency','市场价格必须是货币类型',1),
        array('shop_price','currency','本店价格必须是货币类型',1)
    );


    //这个方法在添加数据库之前会被调用
    // 第一个参数 表单中即将要插入到数据库的数据（数组）
    //且必须要以引用传值 否者无法修改触发传递的是一个对象 因为对象默认是按引用
    protected function _before_insert(&$data,$option){
//        echo '<pre>';
//        var_dump($_FILES);die;
//        //获得时间
        //data 是要插入数据库的数据 以数组的形式传过去
        $data['addtime'] = date('Y-m-d H:i:s',time());
        //我们自己过滤这个字段
        $data['goods_desc'] = removeXss($_POST['goods_desc']);
        $data['brand_id'] = intval($_POST['brand_id']);

        //文件上传
        if($_FILES['logo']['error']==0){
            $upload = new \Think\Upload();// 实例化上传类
            $upload->maxSize = 3145728 ;// 设置附件上传大小
            $upload->exts = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型
            $upload->rootPath = './Public/Upload/'; // 设置附件上传根目录   上传方法的目录设置“根目录 rootPath + 保存目录savepath”
            $upload->savePath = 'Goods/'; // 设置附件上传（子）目录 // 上传文件                      特别注意上传文件夹 后面+“/”表示上传到当前文件下
            $info = $upload->upload();
            if(!$info) {
                //上传错误提示错误信息
                //获取失败信息 并保存在模型里 把错误信息保存到模型的error中然后在控制器会调用这个模型对象的geterror属性 在控制器中获取并打印出来
                $this->error=$upload->getError();
                return false;
            }else{
                //县评出原图的路径
                /**
                 * ["savename"]=>string(17) "591d411dd2147.jpg"
                   ["savepath"]=>string(17) "Goods/2017-05-18/"
                 *   
                 */
//                echo '<pre>';
//                var_dump($info);die;

                //保存后的信息
                $logo = $info['logo']['savepath'].$info['logo']['savename'];   //注意顺序
                //拼出缩略图的路径
                $mbig = $info['logo']['savepath'].'mbig_'.$info['logo']['savename'];   //注意顺序  大图
                $big = $info['logo']['savepath'].'big_'.$info['logo']['savename'];   //注意顺序  超大图
                $sm = $info['logo']['savepath'].'sm_'.$info['logo']['savename'];   //注意顺序   小图
                $mid = $info['logo']['savepath'].'mid_'.$info['logo']['savename'];   //注意顺序  中图

                //上传成功 生成缩略图
                $image = new \Think\Image();  //new 另一个方法图像处理方法
                //打开图片
                $image->open('./Public/Upload/'.$logo);          // 拼接完整的路径 打开要生成缩略图的图片 路径在上传信息里有 打印出来就可以
                //生成缩略图 并保存
                $image->thumb(350,350)->save('./Public/Upload/'.$mbig);  //放在同一个目录下  大图
                $image->thumb(50,50)->save('./Public/Upload/'.$sm);  //放在同一个目录下  小图
                $image->thumb(700,700)->save('./Public/Upload/'.$big);  //放在同一个目录下  超大图
                $image->thumb(130,130)->save('./Public/Upload/'.$mid);  //放在同一个目录下  中图
                //把所有图的路径放到数据库中
                $data['logo'] =  $logo;
                $data['sm_logo'] = $sm;
                $data['mid_logo'] = $mid;
                $data['big_logo'] = $big;
                $data['mbig_logo'] = $mbig;
                //这里就等于在控制器中 实例化模型后的 变量-》数据库字段 = ‘要添加到数据库的数据信息’  这是在add之前做的

            }
        }
    }


    /**************************************** 修改图片之前 ************************************/



    protected function _before_update(&$data,$option){

        /********************* 在更新之前 为is_updated更新内容为1 让sphinx找到 重新创建索引 *************************/
        $data['is_updated'] = 1;

//        var_dump($option);   自带隐藏id  id就是对于字段的id
        $id = $option['where']['id'];//当前商品的id

        /**************************修改商品属性前*********************************/
        $gaid = I('post.goods_attr_id');
        $attrValue = I('post.attr_value');
        $gaModel = D('goods_attr');
        $i = 0;  //定义一个变量 循环用 0和空是相等的
        //$gaid是个一维数组 这里给的变量后面会活循环++ 把$i当做$gaid的下标用 也就是做这个下标就是对应的属性值 有下标的就是修改 没有的是添加
       foreach($attrValue as $k=>$v){
           foreach($v as $k1=>$v1){
               //第二个不用判断直接插入数据库的操作
//               $gaModel->execute('REPLACE INTO p39_goods_attr VALUES("'.$gaid[$i].'","'.$v1.'","'.$k.'","'.$id.'")');
               if($gaid[$i]==''){
                   $gaModel->add(array(
                       'attr_value'=>$v1,
                       'attr_id'=>$k,
                       'goods_id'=>$id,
                   ));
               }else{
                   $gaModel->where(array(
                       'id'=>array('eq',$gaid[$i]),
                   ))->setField('attr_value',$v1);
                   //setfield('字段名称'，修改后的信息)；  用于修改一个字段的时候使用 $v1是二维数组循环后的属性值
               }
               $i++;         //这个是必须的
           }
       }
        /***************************获取要修改的id （在表单的隐藏域中）***************************/
        $id = I('post.id');
//        echo '<pre>';
//        var_dump($_FILES);die;
//        //获得时间
        //data 是要插入数据库的数据 以数组的形式传过去
        $data['addtime'] = date('Y-m-d H:i:s',time());
        //我们自己过滤这个字段  在公共函数内的removeXss自定义函数
        $data['goods_desc'] = removeXss($_POST['goods_desc']);

        //文件上传
        if($_FILES['logo']['error']==0){
            $upload = new \Think\Upload();// 实例化上传类
            $upload->maxSize = 3145728 ;// 设置附件上传大小
            $upload->exts = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型
            $upload->rootPath = './Public/Upload/'; // 设置附件上传根目录   上传方法的目录设置“根目录 rootPath + 保存目录savepath”
            $upload->savePath = 'Goods/'; // 设置附件上传（子）目录 // 上传文件                      特别注意上传文件夹 后面+“/”表示上传到当前文件下
            $info = $upload->upload();
//            var_dump($info);die;
            if(!$info) {
                $this->error=$upload->getError();
                return false;
            }else{
//                echo '<pre>';
//                var_dump($info);die;
                //保存后的信息
                $logo = $info['logo']['savepath'].$info['logo']['savename'];   //注意顺序
                //拼出缩略图的路径
                $mbig = $info['logo']['savepath'].'mbig_'.$info['logo']['savename'];
                $big = $info['logo']['savepath'].'big_'.$info['logo']['savename'];
                $sm = $info['logo']['savepath'].'sm_'.$info['logo']['savename'];
                $mid = $info['logo']['savepath'].'mid_'.$info['logo']['savename'];
                //上传成功 生成缩略图
                $image = new \Think\Image();
                $image->open('./Public/Upload/'.$logo);
                //生成缩略图 并保存  特别注意保持的路径 不要 ——PUBLIC——
                $image->thumb(350,350)->save('./Public/Upload/'.$mbig);
                $image->thumb(50,50)->save('./Public/Upload/'.$sm);
                $image->thumb(700,700)->save('./Public/Upload/'.$big);
                $image->thumb(130,130)->save('./Public/Upload/'.$mid);
                //把所有图的路径放到数据库中
                $data['logo'] =  $logo;
                $data['sm_logo'] = $sm;
                $data['mid_logo'] = $mid;
                $data['big_logo'] = $big;
                $data['mbig_logo'] = $mbig;
//                echo '<pre>';
//                var_dump($data);die;
                //这里就等于在控制器中 实例化模型后的 变量-》数据库字段 = ‘要添加到数据库的数据信息’  这是在add之前做的
                /*************************修改图片*************************/
                /*************************删除原图  不然等于上传了新的图片 而图片路径依然是旧图的路径 依然显示旧图*************/
                /****************************field 主要目的是标识要返回或者操作的字段，可以用于查询和写入操作。******/
                /**********************从数据库查出图片的所有字段信息*******************************/
                $oldLogo = $this->field('logo,sm_logo,mid_logo,big_logo,mbig_logo')->find($id);//根据id查出图片信息
                /***********************因为只能删除图片的信息 所有不能用数据库的删除方式 那样会删除一整条 （根据id）****************/
                /***************系统删除内存中的图片字段信息 取出图片路径 系统删除*****************************/
//                echo '<pre>';
//                var_dump($oldLogo);die;
                unlink('./Public/Upload/'.$oldLogo['logo']);
                unlink('./Public/Upload/'.$oldLogo['sm_logo']);
                unlink('./Public/Upload/'.$oldLogo['mid_logo']);
                unlink('./Public/Upload/'.$oldLogo['big_logo']);
                unlink('./Public/Upload/'.$oldLogo['mbig_logo']);


            }
        }
    }

/*******************取出主分类 和子分类中的商品id***********************/
    public function getGoodesIdBYCatId($catid){
            //先搜索得到子分类的id
            $catmodel = D('Admin/category');
            $children = $catmodel->getChilder($catid);                                           //获得所有分了的子分类方法
            $children[] = $catid;                                                                //把这个当前传过俩的id 和搜到的子分类放到一起 一个数组里 去搜索
        // 因为分类模型中存放找到的子分类是一个以为数组 这里$cheilldren 是一个一维数组！ 后面加【】表示 在这个数组后面加一个键值对 别总想错了 想成二维的 傻逼
            /*****************取出主分类或者拓展分类在这些分类中的商品******************/
            $gids = $this->field('id')->where(array('cat_id'=>array('in',$children),))->select();
            //只取出主分类(找出商品id！！！！ 当分类id在这个分类id数组里的时候);
            //取出主分类的id  把主分类和拓展连在一起
//            echo '<pre>';
//            var_dump($gids);die;
            $gcMolde = D('goods_cat');
            //取出拓展分类中的商品id
            $gidss = $gcMolde->field('DISTINCT goods_id id')
                ->where(array(
                    'cat_id'=>array('IN',$children)))
                ->select();
        //这里取出的是拓展分类下的id
//            echo '<pre>';
//            var_dump($gidss);die;

            if($gids && $gidss){
                $gids = array_merge($gids,$gidss);                //俩个数组合并到一个数组中然后在去重
            }elseif($gidss){
                $gids = $gidss;                                //判断 如果俩个都不为空的时候合并俩个数组
                                                                   // 如果其中一个为空 就把有值得赋值给一个数组的
            }
            /***************二维转一维******************/
        $id = array();
            foreach($gids as $v){
                if(!in_array($v['id'], $id))
                    $id[] = $v['id'];
                $id = array_unique($id);                                 //这里把数组中重复的去掉
            }
//            echo'<pre>'; var_dump($id);die;
        return $id;

    }

    /*******************商品搜素功能************************/
    public function search($perpage=5){
        $gn = I('get.gn');
        $where = array();
        /*
         * 使用查询表达式支持更多的SQL查询语法，查询表达式的使用格式：
         *  $map['字段1'] = array('表达式','查询条件1');
         *  $Model->where($map)->select();
         * 这里where的下标就是数据库字段名称
         * $where['goods_name'] = array('like',%$gn%);  ======== $where( 'goods_name'=array('like',%$gn%));   互相等于
         * array([goods_name]=array(0=>'like',1=>'gn'));
         *$where的小标为数据库需要查的字段名称 为了方便操作
         */
        if($gn){
            $where['goods_name'] =array('like',"%$gn%");   //最后构造成 where ·goods_name·like '%$gn%'
            }

        $fp = I('get.fp');      //开始价
        $tp = I('get.tp');       //终止价

        //三种情况
        if($fp && $tp){
            $where['shop_price'] =array('between',array($fp,$tp));  //最后成成 where shop_price bentween $fp and $tp
        }elseif($fp){
            $where['shop_price'] = array('egt',$fp);             //最后成成 where shop_price>= $fp;
        }elseif($tp){
            $where['shop_price'] = array('elt',$tp);
        }

        /**********************品牌搜索**************************/
        $brand_id = I('get.brand_id');
//        var_dump($brand_id);die();
        if($brand_id){
            $where['brand_id'] = array('eq',$brand_id);
        }

        /**************搜索分类信息 且在搜索前必须也要搜索到子分类的id*****************/
        $catid = I('get.cat_id');
            if($catid){
//            先搜索得到子分类的id
//                $catmodel = D('category');
                $gids = $this->getGoodesIdBYCatId($catid);
                 $children[] = $catid;                            //把这个当前传过俩的id 和搜到的子分类放到一起 一个数组里 去搜索
                 $children = implode(',',$children);
                 $where['cat_id'] = array('in',$children);
//                echo '<pre>';
//                var_dump($gids);die();
//                $where['id'] = array('in',$gids);
        }



/********************************翻页****************************************/
        //取出 总记录数
        $count = $this->where($where)->count();
        // 实例化变量->count（）就等于 在模型自己  $this->count();  就是不用实例化了   //生成翻页类对象
        $pageobj = new \Think\Page($count,$perpage);
        //设置分页样式  美化步骤1
        $pageobj->SetConfig('next','下一页');
        $pageobj->SetConfig('prev','上一页');
        $pagestring = $pageobj->show();

        //取出符合条件的信息
        $data = $this
            ->field('a.*,b.brand_name,c.cat_name')   //因为我要显示商品表中所有商品 所有 别名a 点* 和品牌表的匹配名称  所有这么写  表示只要显示着几个字段的信息
            ->alias('a')
            ->join('LEFT JOIN __BRAND__ b ON a.brand_id=b.id
                    LEFT JOIN __CATEGORY__ c ON a.cat_id=c.id
                 ')
            ->where($where)->limit($pageobj->firstRow.','.$pageobj->listRows)
            ->group('a.id')
            ->select();
        return $data = array(
            'data'=>$data,
            'page'=>$pagestring,
        );

    }

    /********************* 删除指定信息 *********************/
    public function _before_delete($option){
        $id = $option['where']['id'];
        $gcModel = D('goods_cat');
        $gnModel = D('goods_number');
        /***************删除是商品之前 也删除这个商品的库存量*******************/
        $gnModel ->where(array(
            'goods_id'=>array('eq',$id),
        ))->delete();
        /********************删除拓展分类******************************/

        $gcModel->where(array(
            'goods_id'=>array('eq',$id))
        )->delete();

        /*************删除商品之前 删除对应的商品属性************/
        $gaModel = D('goods_attr');
        $gaModel->where(array(
            'goods_id'=>array('eq',$id),
        ))->delete();


        //删除之前的钩子函数  删除5张图片
        $id = I('get.id');  //====$id = $option['where']['id']    $option 会自带id值过来
        /**********************从数据库查出图片的所有字段信息*******************************/
        $oldLogo = $this->field('logo,sm_logo,mid_logo,big_logo,mbig_logo')->find($id);//根据id查出图片信息
        /***********************因为只能删除图片的信息 所有不能用数据库的删除方式 那样会删除一整条 （根据id）****************/
        /***************系统删除内存中的图片字段信息 取出图片路径 系统删除*****************************/
//                echo '<pre>';
//                var_dump($oldLogo);die;
        unlink('./Public/Upload/'.$oldLogo['logo']);
        unlink('./Public/Upload/'.$oldLogo['sm_logo']);
        unlink('./Public/Upload/'.$oldLogo['mid_logo']);
        unlink('./Public/Upload/'.$oldLogo['big_logo']);
        unlink('./Public/Upload/'.$oldLogo['mbig_logo']);
        /***********因为有一个删除的函数deleteImage（）；  系统自动找到 所有只要调用这个函数 把获取到的信息传导函数内 就可以删除**********/
//        deleteImage($oldLogo);   即可删除  在函数体内删除系统内存图片信息 定义的函数


    }



    /*************添加之后的函数**********************/
    public function _after_insert($data,$option){
//        $data['id']就是添加之后的商品id  在tp里可以这么用 字段传过来的
//        正常是 $model = D('Goods');
//        $id = $model->add($data = array('id'=>$_POST['id'],'name'=>$name,...... ))  这时 $id 就等于当前插入数据库的id字段的当前id
        $mp = I('post.member_price'); //获得的是以为数组
        $mpModel = D('Member_price');
        if($mp){
            foreach ($mp as $k=> $mval){
                $v = (float)$mval;                                               //转换为浮点型  防止输入非数字
                /**
                 * if($v == 0)         //如果这个数字等于0 跳过
                        continue;
                 */
                if($v>0){                                                         //或者这么写 文本框输入的价格大于0 才执行下面的数组
                    $mpModel->add(array(
                        'price'=>$v,
                        'member_id'=>$k,
                        'goods_id'=>$data['id'],
                    ));
                }
            }
        }


        /*********************添加到相册*******************/
        $gpModel = D('goods_pic');
        $gpModel->add(
            array(
                'sm_pic'=>$data['sm_logo'],
                'mid_pic'=>$data['mid_logo'],
                'big_pic'=>$data['big_logo'],
                'mbig_pic'=>$data['mbig_logo'],
                 'goods_id'=>$data['id'],)
        );

/****************拓展分类插入信*********************/
        $goods_cat=I('post.ext_cat_id');
        if($goods_cat){
            $cat_model = D('goods_cat');          //实例化拓展分类表
            foreach($goods_cat as $v){
                if($v){                     //如果传过来的没有数据 就不添加
                    $cat_model->add(array(
                        'cat_id'=>$v,
                        'goods_id'=>$data['id'],
                    ));
                }
            }
        }

        /*********************处理添加商品属性信息*******************/
        $gaModel = D('goods_attr');
        $attrValue = I('post.attr_value');

        foreach($attrValue as $k=>$v){
            //把属性值去重 以免 有重复添加的
            $v = array_unique($v);
            foreach($v as $k1=>$v1){
                $gaModel->add(array(
                    'goods_id'=>$data['id'],
                    'attr_id'=>$k,
                    'attr_value'=>$v1,
                ));
            }
        }


    }




    /******************取出抢购的商品 $limit 代表取出几个商品*******************************/
    //gt "大于号"
    //elt "小于于等于号"
    //egt "大于等于号"
    //开始时间小于等于今天  结束时间大于等于今天

    public function getRromotegoods($limit = 5){
        $today = date('Y-m-d H:i');
        $data = $this->field('id,goods_name,mid_logo,promote_price')
            ->where(array(
            'is_on_sale'=>array('eq','是'),
            'promote_price'=>array('gt',0),
            'promote_start_date'=>array('elt',$today),
            'promote_end_date'=>array('egt',$today),
        ))->limit($limit)
            ->order('sort_num ASC')
            ->select();
        return $data;
    }

    /*******************取是新品 还是热卖的 还是推荐的**************************/
    //通过传一个参数 来取是新品 还是热卖的 还是推荐的 $recType
    //这个变量代表每一种产品
    public function getRecgoods($recType,$limit = 5){
        $data = $this->field('id,goods_name,mid_logo,shop_price')
            ->where(array(
                'is_on_sale'=>array('eq','是'),
                "$recType" =>array('eq','是'),
            ))->limit($limit)
            ->order('sort_num ASC')
            ->select();
        return $data;
    }

    /*******************获取会员的价格**************************/
    public function getMemberPrice($goodsId){
        /********先查出这个会员的等级 根据积分到积分等级表去找 * 已经在会员模型中取到并存session了******/
        //这里要判断一下有没有登陆
        $date = date('Y-m-d H:i');
        $levelId = session('level_id');
//获取商品的促销价格
        $promotePrice = $this->field('promote_price')->where(array(
            'id'=>array('eq',$goodsId),
            'promote_price'=>array('gt',0),
            'promote_start_date'=>array('elt',$date),               //商品的促销开始时间必须是小于今天的
            'promote_end_date'=>array('egt',$date),                   //商品的促销结束时间必须是大于今天的
        ))->find();
        if($levelId){
            $mpModel = D('member_price');
            $mpData =  $mpModel->field('price')->where(array(
                'goods_id'=>array('eq',$goodsId),
                'member_id'=>array('eq',$levelId),          //会员积分等级
            ))->find();
            //判断如果没有这个等级的价格 就还回本店价格
            if($mpData['price']) {
                if($promotePrice['promote_price']){
                    return min($promotePrice['promote_price'],$mpData['price']);           //如果有促销价格 判断谁小就取谁
                }else{
                    return $mpData['price'];                                                //如果没有就还是取本店价格
                }
                //如果没有这个等级的价格就直接取出本店的价格放上去
            }else{
               $p = $this->field('shop_price')->find($goodsId);
                if($promotePrice['promote_price']){
                    return min($promotePrice['promote_price'],$p['shop_price']);           //如果有促销价格 判断谁小就取谁
                }else{
                    return $p['shop_price'];                                                //如果没有就还是取本店价格
                }
            }
            //如果没有登录就返回这个价格（本店价格）
        }else{
            $p = $this->field('shop_price')->find($goodsId);
            if($promotePrice['promote_price']){
                return min($promotePrice['promote_price'],$p['shop_price']);           //如果有促销价格 判断谁小就取谁
            }else{
                return $p['shop_price'];                                                //如果没有就还是取本店价格
            }

        }


    }

    /**
     * 获得某一个分类下一页的商品
     */
    public function cat_search($catId,$perpage = 60){
        //根据分类id找到这个id下的所有商品id

        $goodsId = $this->getGoodesIdBYCatId($catId);
//        $where['a.id'] = array('in',$goodsId);
        /*****************************翻页*********************************/
        $count = $this->alias('a')->where(array('a.id' => array('in',$goodsId),))->count();
//        var_dump($count);die;       ok
        $page = new\Think\Page($count,$perpage);
        //翻页模式
        $page->setConfig('prev','上一页');
        $page->setConfig('next','下一页');
        $data['page'] = $page->show();
//        var_dump($data['page']);die;  ok
        /*******************************取数据******************************/
        //商品表中取出相关字段信息 和 订单表中取出所有商品卖出数量之和最大的改名称为 xl
        // 链表查出订单商品表里的id 等于商品表里的id 和订单商品表里的id要在订单基本信息表里 并且这个id的付款状态要必须是已经付款的
        $data['data'] = $this->alias('a')
            ->field('a.id,a.goods_name,a.mid_logo,a.shop_price,SUM(b.goods_number) xl')
            ->join('LEFT JOIN __ORDER_GOODS__ b
				 ON (a.id=b.goods_id
				      AND
				     b.order_id IN(SELECT id FROM __ORDER__ WHERE pay_status="是"))')
            ->where(array('a.id' => array('in',$goodsId),))
            ->group('a.id')
            ->limit($page->firstRow.','.$page->listRows)
            ->order('xl desc')
            ->select();
//        return $data;
//        echo "<pre>";
//        var_dump($data['data']);die;
    }


    /**
     * 获取某个关键字下某一页的商品
     *
     * @param unknown_type $key
     * @param unknown_type $perPage
     */
    public function key_search($key, $pageSize = 6)
    {
        /*************** 搜索 *************************/
        //根据关键字搜索匹配【商品属性值，商品描述，商品名称】 得到商品的id 和商品的属性名称
        $goodsId = $this->alias('a')
            ->field('GROUP_CONCAT(DISTINCT a.id) gids')
            ->join('LEFT JOIN __GOODS_ATTR__ b ON a.id=b.goods_id')
            ->where(array(
                'a.is_on_sale' => array('eq', '是'),
                'a.goods_name' => array('exp', " LIKE '%$key%' OR a.goods_desc LIKE '%$key%' OR attr_value LIKE '%$key%'"),
            ))
            ->find();
//        echo '<pre>';
//        var_dump($goodsId['gids']);
//        die;
        $goodsId = explode(',', $goodsId['gids']);  //多个商品id 转换为数组


        $where['a.id'] = array('in', $goodsId);
        // 品牌
        $brandId = I('get.brand_id');
        if($brandId)
            $where['a.brand_id'] = array('eq', (int)$brandId);
        // 价格
        $price = I('get.price');
        if($price)
        {
            $price = explode('-', $price);
            $where['a.shop_price'] = array('between', $price);
        }

        /******************************************* 商品搜索开始 ************************************************/
        $gaModel = D('goods_attr');
        $attrGoodsId = NULL;  // 根据每个属性搜索出来的商品的ID
        // 根据属性搜索 : 循环所有的参数找出属性的参数进行查询
        foreach ($_GET as $k => $v)
        {
            // 如果变量是以attr_开头的说明是一个属性的查询, 格式：attr_1/黑色-颜色
            if(strpos($k, 'attr_') === 0)
            {
                // 先解析出属性ID和属性值
                $attrId = str_replace('attr_', '', $k); // 属性id
                // 先取出最后一个-往后的字符串
                $attrName = strrchr($v, '-');
                $attrValue = str_replace($attrName, '', $v);
                // 根据属性ID和属性值搜索出这个属性值下的商品id：并返回一个字符串格式：1,2,3,4,5,6,7
                $gids = $gaModel->field('GROUP_CONCAT(goods_id) gids')->where(array(
                    'attr_id' => array('eq', $attrId),
                    'attr_value' => array('eq', $attrValue),
                ))->find();
                // 判断是有商品
                if($gids['gids'])
                {
                    $gids['gids'] = explode(',', $gids['gids']);
                    // 说明是搜索的第一个属性
                    if($attrGoodsId === NULL)
                        $attrGoodsId = $gids['gids'];  // 先暂存起来
                    else
                    {
                        // 和上一个属性搜索出来的结果求集
                        $attrGoodsId = array_intersect($attrGoodsId, $gids['gids']);
                        // 如果已经没有商品满足条件就不用再考虑下一个属性了
                        if(empty($attrGoodsId))
                        {
                            $where['a.id'] = array('eq', 0);
                            break;
                        }
                    }
                }
                else
                {
                    // 前几次的交集结果清空
                    $attrGoodsId = array();
                    // 如果这个属性下没有商品就应该向where中添加一个不可能满足的条件，这样后面取商品时就取不出来了！
                    $where['a.id'] = array('eq', 0);
                    // 取出循环，不用再查询下一个属性了
                    break;
                }
            }
        }
        // 判断如果循环求次之后这个数组还不为空说明这些就是满足所有条件的商品id
        if($attrGoodsId)
            $where['a.id'] = array('IN', $attrGoodsId);
        /******************************************* 商品搜索结束 ************************************************/



        /**************** 翻页 *********************/
        // 取出总的记录数，以及所有的商品ID的字符串
        //$count = $this->alias('a')->where($where)->count();  // 这个只能取总记录数，改成下面这行，即取总记录数，又取出了商品ID
        $count = $this->alias('a')->field('COUNT(a.id) goods_count,GROUP_CONCAT(a.id) goods_id')->where($where)->find();
        // 把商品ID返回
        $data['goods_id'] = explode(',', $count['goods_id']);

        $page = new \Think\Page($count['goods_count'], $pageSize);
        // 配置翻页的样式
        $page->setConfig('prev', '上一页');
        $page->setConfig('next', '下一页');
        $data['page'] = $page->show();

        /*********************** 排序 ********************/
        $oderby = 'xl';    // 默认
        $oderway = 'desc'; // 默认
        $odby = I('get.odby');
        if($odby)
        {
            if($odby == 'addtime')
                $oderby = 'a.addtime';
            if(strpos($odby, 'price_') === 0)
            {
                $oderby = 'a.shop_price';
                if($odby == 'price_asc')
                    $oderway = 'asc';
            }
        }

        /**************** 取数据 ********************/
        $data['data'] = $this->alias('a')
            ->field('a.id,a.goods_name,a.mid_logo,a.shop_price,SUM(b.goods_number) xl')
            ->join('LEFT JOIN __ORDER_GOODS__ b
				 ON (a.id=b.goods_id
				      AND
				     b.order_id IN(SELECT id FROM __ORDER__ WHERE pay_status="是"))')
            ->where($where)
            ->group('a.id')
            ->limit($page->firstRow.','.$page->listRows)
            ->order("$oderby $oderway")
            ->select();

        return $data;
    }

}
